package cn.itsource.service.impl;

import cn.itsource.client.RedisClient;
import cn.itsource.client.SmsClient;
import cn.itsource.domain.Sso;
import cn.itsource.mapper.SsoMapper;
import cn.itsource.service.IVerifycodeService;
import cn.itsource.util.AjaxResult;
import cn.itsource.util.StrUtils;
import cn.itsource.util.VerifyCodeUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class VerifycodeServiceImpl implements IVerifycodeService {

    @Autowired
    private SsoMapper ssoMapper;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private SmsClient smsClient;
    @Override
    public String getImageCode(String imageCodeKey) {
        try{
            // 1 生成随机验证码 123456
            String imageCode = VerifyCodeUtils
                    .generateVerifyCode(6).toLowerCase();
            System.out.println(imageCode);
            // 2 以imageCodeKey作为key存放验证到redis 1分钟过期
            redisClient.addForTime(imageCodeKey,imageCode,60*5);
            // 2 生成图片验证码图片 util
            ByteArrayOutputStream data = new ByteArrayOutputStream();
            VerifyCodeUtils.outputImage(100, 40, data, imageCode);
            // 3 图片通过base64加密返回
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(data.toByteArray());
        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;

    }

    @Override
    public AjaxResult sendSmsCode(Map<String, String> params) {
        // 一 接收参数
        //手机号
        String mobile = params.get("mobile");
        //图片验证码
        String imageCode = params.get("imageCode");
        //图片验证码的key
        String imageCodeKey = params.get("imageCodeKey");
        // 二 做检验
        //2.1 图片验证 通过key从redis获取存放验证码和输入的进行对比
        String imgCodeforReids = redisClient.get(imageCodeKey);
        if (imgCodeforReids==null || !imageCode.equals(imgCodeforReids)){
            return AjaxResult.me().setSuccess(false).setMessage("图片验证码不正确!");
        }
        //2.2 手机号的验证-判null，是否已经注册了
        if (mobile==null){
            return AjaxResult.me().setSuccess(false).setMessage("请输入正确的手机号码");
        }
        List<Sso> ssos = ssoMapper
                .selectList(new EntityWrapper<Sso>().eq("phone", mobile));
        if (ssos!=null && ssos.size()>0){
            return AjaxResult.me().setSuccess(false).setMessage("你的手机号已经注册了，可以直接使用！");
        }
        // 三 发送短信验证码
        return sendSmsCode(mobile);
    }

    private AjaxResult sendSmsCode(String mobile) {
        String smsKey = "SMS_CODE:"+mobile;
        // 一 先产生一个验证码
        String smsCode = StrUtils.getComplexRandomString(4);   //面条 饭
        //二 如果原来验证码有效,替换生成哪个
        String smsCodeForRedis= redisClient.get(smsKey); //smsCode格式 code:time
        if (StringUtils.hasLength(smsCodeForRedis)){
            //2如果有效,判断是否已经过了重发时间,如果没有过就报错
            String[] split = smsCodeForRedis.split(":");
            String timeStr = split[1];
            long time = System.currentTimeMillis()-Long.valueOf(timeStr);
            if (time<1000*60){
                return AjaxResult.me().setSuccess(false).setMessage("请不要重复发送短信验证码!");
            }
            //如果过了,替换原来的验证码
            smsCode = split[0];
        }
        //三 存储到redis
        redisClient.addForTime(smsKey,smsCode+":"+System.currentTimeMillis(),60*5);//5分钟过期
        //四 都要进行发送
        System.out.println("[源码科技]已经发送验证码"+smsCode+"到用户手机:"+mobile);
        Map<String,String> params = new HashMap<>();
        //smsMob=手机号码&smsText=验证码:8888
        params.put("smsMob",mobile);
        params.put("smsText","验证码为:"+smsCode+",请在5分钟之内使用!");

        smsClient.send(JSONObject.toJSONString(params));
        return AjaxResult.me();
    }
}
